ZonesService   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Test Coverage

Coverage 95.12%

Importance

Changes 0
Metric Value
eloc 76
dl 0
loc 112
ccs 39
cts 41
cp 0.9512
rs 10
c 0
b 0
f 0
wmc 11

5 Functions

Rating   Name   Duplication   Size   Complexity  
A findByCity 0 7 1
A findAll 0 4 1
A getZoneTypesForPosition 0 28 3
B getZonesByFilter 0 50 5
A pointInParkingZone 0 7 1
1 11
import { Injectable } from '@nestjs/common';
2 11
import { InjectRepository } from '@nestjs/typeorm';
3 11
import { Repository } from 'typeorm';
4 11
import { Zone } from './entities/zone';
5
import { ZoneQuery } from './types/ZoneQuery';
6
import { ZoneResponse } from './types/ZoneResponse';
7 11
import { BicyclesService } from 'src/bicycles/bicycles.service';
8 11
import { getDistance, positionInsidePolygon } from 'src/utils/geo.utils';
9
import { CityName } from 'src/cities/types/city.enum';
10
11
@Injectable()
12 11
export class ZonesService {
13
  constructor(
14
    @InjectRepository(Zone)
15 24
    private readonly zoneRepository: Repository<Zone>,
16 24
    private readonly bicyclesService: BicyclesService,
17
  ) {}
18
19
  async findAll(): Promise<Zone[]> {
20 37
    return await this.zoneRepository.find({
21
      relations: ['speedZone', 'city'],
22
    });
23
  }
24
25
  async findByCity(cityName: CityName): Promise<Zone[]> {
26 3
    return await this.zoneRepository.find({
27
      relations: ['city'],
28
      where: {
29
        city: {
30
          name: cityName,
31
        },
32
      },
33
    });
34
  }
35
36
  // seems unused
37
  // async getZones(lat: number, lon: number): Promise<Zone[]> {
38
  //   let zones = await this.findAll();
39
  //   zones = zones.filter((zone) => {
40
  //     return positionInsidePolygon(lat, lon, zone.polygon);
41
  //   });
42
  //   return zones;
43
  // }
44
45
  async getZonesByFilter(query: ZoneQuery): Promise<ZoneResponse> {
46 10
    const zones: ZoneResponse = {
47
      zones: [],
48
    };
49 10
    zones.zones = await this.findAll();
50
51 10
    if (query.city && query.city.length > 0) {
52 3
      zones.zones = zones.zones.filter((zone) => {
53 17
        return query.city.includes(zone.city.name);
54
      });
55
    }
56
57 10
    if (query.type && query.type.length > 0) {
58 3
      zones.zones = zones.zones.filter((zone) => {
59 16
        return query.type.includes(zone.type);
60
      });
61
    }
62
63 10
    if (query.lat && query.lon) {
64 2
      zones.zones = zones.zones.filter((zone) => {
65 14
        return (
66
          getDistance(query.lat, query.lon, zone.polygon[0].lat, zone.polygon[0].lng) <= query.rad
67
        );
68
      });
69
    }
70
71 10
    if (query.includes && query.includes.length > 0) {
72 3
      const allBikes = await this.bicyclesService.findAll();
73 3
      zones.zones = zones.zones.map((zone) => {
74 15
        const bikes = allBikes.filter((bike) => {
75 404
          return positionInsidePolygon(bike.latitude, bike.longitude, zone.polygon);
76
        });
77 15
        return {
78
          ...zone,
79
          bikes: bikes,
80
        };
81
      });
82
    }
83
84 10
    return zones;
85
  }
86
87
  async getZoneTypesForPosition(lat: number, lon: number): Promise<string[]> {
88 3
    const parkingZones = (await this.findAll()).filter((zone) => {
89 33
      return zone.type === 'parking';
90
    });
91 3
    const chargingZones = (await this.findAll()).filter((zone) => {
92 33
      return zone.type === 'charging';
93
    });
94
95 3
    const parking = parkingZones.some((zone) => {
96 15
      return positionInsidePolygon(lat, lon, zone.polygon);
97
    });
98
99 3
    const charging = chargingZones.some((zone) => {
100 9
      return positionInsidePolygon(lat, lon, zone.polygon);
101
    });
102
103 3
    const types = [];
104
105 3
    if (parking) {
106
      types.push('Parking');
107
    }
108
109 3
    if (charging) {
110
      types.push('Charging');
111
    }
112
113 3
    return types;
114
  }
115
116
  async pointInParkingZone(lat: number, lon: number): Promise<boolean> {
117 20
    const zones = (await this.findAll()).filter((zone) => {
118 204
      return zone.type === 'parking';
119
    });
120 20
    return zones.some((zone) => {
121 58
      return positionInsidePolygon(lat, lon, zone.polygon);
122
    });
123
  }
124
}
125